<?php

class ForestModel extends aBaseModel implements Iterator,ArrayAccess
{
	/**
	 * 树木数组
	 * @var Tree array
	 */
	private $_tree;

	/**
	 * 森林实例
	 * @var Forest
	 */
	private static $_forest = array();

	/**
	 * 树木枯萎值
	 * @var int
	 */
	private $_died;

	/**
	 * 森林水资源
	 * @var int
	 */
	private $_water = 0;

	/**
	 * 森林死亡状态，0表示死了，1表示活着
	 * @var [0,1]
	 */
	private $_dieStatus = 1;
	
	/**
	 * 类构造方法
	 * @access private
	 */
	protected function __construct( $userId )
	{
		$this->userId = $userId;
		$this->_tree = array();
		$this->_cacheEngine = & Common::getCache();
		$this->_ini();
	}

	/**
	 * 获取惟一实例
	 * @access public
	 * @return Forest
	 */
	public static function &getInstance( $userId )
	{
		if( !isset( self::$_forest[ $userId ] ) || self::$_forest[ $userId ] == null )
		{
			self::$_forest[ $userId ] = new ForestModel( $userId );
		}
		return self::$_forest[ $userId ];
	}

	/**
	 * 类初始化方法，在构造方法中调用
	 * @access private
	 */
	private function _ini()
	{
		$db = Common::getDB( $this->userId );
		$treeIds = $db->findAll( 'lw_tree' , 'tid' , array( 'uid' => $this->userId ) );
		if ( !is_array( $treeIds ) )
		{
			//用户森林中没树了
			TreeModel::addSeed( $this->userId );
			echo $db->getLastSql();
		}
		else 
		{
			foreach ( $treeIds as $val ) 
			{
				//先从缓存取数据
				$cacheData = $this->_cacheEngine->get( "tree_{$val['tid']}" );
				if ( $cacheData )
				{
					$this->_tree[ $val['tid'] ] = $cacheData;
				}
				else
				{
					$this->_tree[ $val['tid'] ] = TreeModel::getInstance( $this->userId , $val['tid'] , false );
					$this->_cacheEngine->add( "tree_{$val['tid']}" , $this->_tree[ $val['tid'] ] );
				}
			}
		}
		$this->_water = UserModel::getInstance( $this->userId , false )->getWater( $this->userId );
	}

	/**
	 * 定义森林的成长机制
	 * @return mixed
	 */
	public function grow()
	{
		$this->_water += Common::getConfig( 'forest_grow_add_water' );
		if( count( $this->_tree ) === 0 )
		{
			return false;
		}
		foreach ( $this as $tree )
		{
			if( $tree->getDied() )
			{
				continue;
			}
			elseif( $tree->getDry() )
			{
				/**
				 * 有30%的几率可以把干枯的树木，消耗2点水可以把树木救活，
				 * 但是本次森林的成长中，树木不会得到成长；
				 * 如果树木没有被救活，或者水依然不足，
				 * 则树木就会变成死亡状态。
				 */
				if( ( $this->_water >= Common::getConfig( 'tree_turn_live' ) ) && Common::computeResult( Common::getConfig( 'tree_turn_live_chance' ) ) )
				{
					$this->_water -= Common::getConfig( 'tree_turn_live' );
					$tree->setDry( 0 );
				}
				else
				{
					$tree->setDied( 1 );
				}
			}
			else
			{
				/*	//原来的状态
				$oldStatus = $tree->getStatus();
				$tree->grow();
				//成长后的状态
				$newStatus = $tree->getStatus();*/
				//一棵树从一个状态，转换到另外一个状态时，需要消耗水
				$hadChangeStatus = $tree->grow();
				if( $hadChangeStatus )
				{
					//所剩的水不能满足树的成长需要，树变干枯
					//echo $tree->getStatus() ."<br />";
					if( $this->_water < Common::getConfig( 'tree_changeStatus_use_water' ) )
					{
						// echo $tree->getStatus() ."<br />";
						$tree->setDry( 1 );
						continue;
					}
					else
					{
						$this->_water -= Common::getConfig( 'tree_changeStatus_use_water' );
					}
				}
				//每1颗结果后的树都会在森林中掉下一个种子
				if( $tree->getStatus() == TreeModel::HAD_GAINS && !$tree->getDied() && $tree->getFruitGrowthValue() == 0 && $hadChangeStatus )
				{
					$tree->addSeed( $this->userId );
				}
			}
			$tree->save();
		}
		$this->updateToDb( 'lw_user' , self::DATA_ACTION_UPDATE , array( "water" => $this->_water ) );
	}

	/**
	 * 返回当前森林的树木数量
	 * @return int number
	 */
	public function getTreesNum()
	{
		return count( $this->_tree );
	}

	public function getWaterNum()
	{
		return $this->_water;
	}

	public static function getInformation( $forest = null )
	{
		$forest = $forest ? $forest : self::getInstance();
		echo "<br />森林的树木总量为：" . $forest->getTreesNum();
		echo "<br />森林的水总量为：" . $forest->getWaterNum();
		$seedCounter = $seedlingCounter = $littleTreeCounter = $bigTreeCounter = $gainTreeCounter = $wizenedCounter = $diedCounter = 0;
		foreach ( $forest as $tree )
		{
			switch( $tree->getStatus() )
			{
				case TreeModel::SEED:
					$seedCounter++;
					break;
				case TreeModel::SEEDLING:
					$seedlingCounter++;
					break;
				case TreeModel::LITTLE_TREE:
					$littleTreeCounter++;
					break;
				case TreeModel::BIG_TREE:
					$bigTreeCounter++;
					break;
				case TreeModel::HAD_GAINS:
					$gainTreeCounter++;
					break;
				default:
					return false;
					break;
			}
			if( $tree->getWizened() )
			{
				$wizenedCounter++;
			}
			if( $tree->getDied() )
			{
				$diedCounter++;
			}
		}
		echo "<br />森林的种子总量为：" . $seedCounter;
		echo "<br />森林的小苗总量为：" . $seedlingCounter;
		echo "<br />森林的小树总量为：" . $littleTreeCounter;
		echo "<br />森林的大树总量为：" . $bigTreeCounter;
		echo "<br />森林的结果树总量为：" . $gainTreeCounter;
		echo "<br />森林的枯树总量为：" . $wizenedCounter;
		echo "<br />森林的死树总量为：" . $diedCounter;
	}
	
	public function addTree( $tid )
	{
		$this->_tree[ $tid ] = TreeModel::getInstance( $this->userId , $tid );
	}

	public function rewind()
	{
		reset( $this->_tree );
	}

	public function current()
	{
		return current( $this->_tree );
	}

	public function next()
	{
		return next( $this->_tree );
	}

	public function key()
	{
		return key( $this->_tree );
	}

	public function valid()
	{
		return $this->current() != false;
	}

	public function offsetExists( $offset )
	{
		return array_key_exists( $offset , $this->_tree );
	}

	public function offsetGet( $offset )
	{
		if( $this->offsetExists( $offset ) )
		{
			return $this->_tree[ $offset ];
		}
		return false;
	}

	public function offsetSet( $offset , $value )
	{
		if( $this->offsetExists( $offset ) )
		{
			$this->_tree[ $offset ] = $value;
		}
	}

	public function offsetUnset( $offset )
	{
		if( $this->offsetExists( $offset ) )
		{
			unset( $this->_tree[ $offset ] );
		}
	}
	
	protected function formatToDBData( $table , $data )
	{
		return $data;
	}
	
	protected function formatFromDBData( $table , $data )
	{
		return $data;
	}
	
	protected function emptyDataWhenloadFromDB( $table )
	{
		$data = array();
		return $data;
	}

	public function __clone()
	{
		self::$_forest = $this;
	}
}